library IEEE;
use IEEE.std_logic_1164.all;

entity sixteenbitreg is
	port (d : in std_logic_vector(15 downto 0);
		q : out std_logic_vector(15 downto 0);
		en,clk : in std_logic);
end sixteenbitreg;

architecture dataflow of sixteenbitreg is
begin
	process(clk)
	begin
		if clk'EVENT and clk = '1' then
			if en = '1' then
				q <= d;
			end if;
		end if;
	end process;
end dataflow;

library IEEE;
use IEEE.std_logic_1164.all;

entity fourto1mux is
	port (a,b,c,d : in std_logic;
		output : out std_logic;
		s : in std_logic_vector(1 downto 0));
end fourto1mux;

architecture logic of fourto1mux is
begin
	output <= (not s(1) and not s(0) and a) or
			  (not s(1) and s(0) and b) or
			  (s(1) and not s(0) and c) or
			  (s(1) and s(0) and d);
end logic;

library IEEE;
use IEEE.std_logic_1164.all;

entity sixteenbit4to1mux is
	port (A,B,C,D : in std_logic_vector(15 downto 0);
		sel : in std_logic_vector(1 downto 0);
		output : out std_logic_vector(15 downto 0));
end sixteenbit4to1mux;

architecture structure of sixteenbit4to1mux is
	component fourto1mux
	port (a,b,c,d : in std_logic;
		output : out std_logic;
		s : in std_logic_vector(1 downto 0));
	end component;
begin

	mux_gen : for i in 0 to 15 generate
		onemux : fourto1mux
			port map(A(i),B(i),C(i),D(i), output(i), sel);
	end generate;
end structure;

library IEEE;
use IEEE.std_logic_1164.all;

entity two2fourdecoder is
	port (addr : in std_logic_vector(1 downto 0);
		output : out std_logic_vector(3 downto 0));
end two2fourdecoder;

architecture behavior of two2fourdecoder is
begin
	with addr select
		output <= "0001" when "00",
				  "0010" when "01",
				  "0100" when "10",
				  "1000" when "11",
				  "0000" when others;
end behavior;

library IEEE;
use IEEE.std_logic_1164.all;

entity registerfile is
	port (rd_reg1,rd_reg2,wr_reg : in std_logic_vector(1 downto 0);
		wr_data : in std_logic_vector(15 downto 0);
		Reg1, Reg2 : out std_logic_vector(15 downto 0);
		reg_write : in std_logic);
end registerfile;

architecture structure of registerfile is
	component sixteenbitreg
		port (d : in std_logic_vector(15 downto 0);
			q : out std_logic_vector(15 downto 0);
			en,clk : in std_logic);
	end component;
	
	component sixteenbit4to1mux
		port (A,B,C,D : in std_logic_vector(15 downto 0);
			sel : in std_logic_vector(1 downto 0);
			output : out std_logic_vector(15 downto 0));
	end component;

	component two2fourdecoder
		port (addr : in std_logic_vector(1 downto 0);
		output : out std_logic_vector(3 downto 0));
	end component;
	
	signal dataA,dataB,dataC,dataD : std_logic_vector(15 downto 0);
	signal en : std_logic_vector(3 downto 0);
begin
	decode : two2fourdecoder
		port map(wr_reg, en);
	reg_0 : sixteenbitreg
		port map(wr_data, dataA, en(0),reg_write);
	reg_1 : sixteenbitreg
		port map(wr_data, dataB, en(1),reg_write);
	reg_2 : sixteenbitreg
		port map(wr_data, dataC, en(2),reg_write);
	reg_3 : sixteenbitreg
		port map(wr_data, dataD, en(3),reg_write);

	mux1 : sixteenbit4to1mux
		port map(dataA,dataB,dataC,dataD,rd_reg1,Reg1);

	mux2 : sixteenbit4to1mux
		port map(dataA,dataB,dataC,dataD,rd_reg2,Reg2);
end structure;

library IEEE;
use IEEE.std_logic_1164.all;

package mips_package3 is
	component sixteenbitreg
		port (d : in std_logic_vector(15 downto 0);
			q : out std_logic_vector(15 downto 0);
			en,clk : in std_logic);
	end component;
	component registerfile
		port (rd_reg1,rd_reg2,wr_reg : in std_logic_vector(1 downto 0);
			wr_data : in std_logic_vector(15 downto 0);
			Reg1, Reg2 : out std_logic_vector(15 downto 0);
			reg_write : in std_logic);
	end component;
end mips_package3;


